package trading_strategy.markets;

import trading_strategy.Entity;
import trading_strategy.events.EventProvider;

import java.util.*;

/**
 * Created by IntelliJ IDEA.
 * User: gderoujoux
 * Date: 6 mai 2010
 * Time: 11:00:52
 * To change this template use File | Settings | File Templates.
 */
public class Market extends Entity {
    String currencyId;
    ITransactionCosts transactionCosts;
    final EventProvider marketEventProvider;

    final static Map<Integer, Market> markets = new HashMap<Integer, Market>();

    public Market(Integer id, String currenyId, ITransactionCosts tc) {
        super(id);
        this.currencyId = currencyId;
        this.transactionCosts = tc;
        synchronized (markets) {
            markets.put(id, this);
        }
        marketEventProvider = new EventProvider(getId() + "-marketevents", getId() + "-market");
    }

    public static Market getMarket(Integer marketId) {
        synchronized (markets) {
            return markets.get(marketId);
        }
    }

    public Date getNextOpenDate(Date date) {
        Calendar cal = GregorianCalendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 8);
        cal.set(Calendar.MINUTE, 15);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        if (cal.getTime().before(date)) {
            cal.add(Calendar.DAY_OF_YEAR, 1);
        }
        // Make sure it is an open day
        while (closedDay(cal)) {
            cal.add(Calendar.DAY_OF_YEAR, 1);
        }
        return cal.getTime();
    }

    public Date getNextCloseDate(Date date) {
        Calendar cal = GregorianCalendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 20);
        cal.set(Calendar.MINUTE, 30);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MILLISECOND, 0);

        if (cal.getTime().before(date)) {
            cal.add(Calendar.DAY_OF_YEAR, 1);
        }
        // Make sure it is an open day
        while (closedDay(cal)) {
            cal.add(Calendar.DAY_OF_YEAR, 1);
        }
        return cal.getTime();
    }

    private boolean closedDay(Calendar cal) {
        final int dow = cal.get(Calendar.DAY_OF_WEEK);
        if (dow == Calendar.SATURDAY || dow == Calendar.SUNDAY) {
            return true;
        }
        return false;
    }

    public EventProvider getMarketEventProvider() {
        return marketEventProvider;
    }

    public ITransactionCosts getTransactionCosts() {
        return transactionCosts;
    }
}
